package com.util;

import com.qiniu.util.Hex;
import com.wechat.mp.WxAccessToken;
import org.springframework.util.DigestUtils;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.Random;

public class JsSDKUtil {
    public static Map<String, String> makeWXTicket(String url) {
        String jsApiTicket = null;
        try {
            String mAccess_token = WxAccessToken.getSavedAccessToken();
            jsApiTicket = WxAccessToken.getSavedJsapiTicket(mAccess_token);

            Map<String, String> ret = new HashMap<String, String>();
            String timestamp = createTimestamp();
            String noncestr = getNonceStr();
            /*-----------------------*/
            Map<String, String> params = new HashMap<String, String>();
            params.put("jsapi_ticket", jsApiTicket);
            params.put("noncestr", noncestr);
            params.put("timestamp", timestamp);
            params.put("url", url);
            //1.1 对所有待签名参数按照字段名的ASCII 码从小到大排序（字典序）
            Map<String, String> sortParams = sortAsc(params);
            //1.2 使用URL键值对的格式拼接成字符串
            String str = mapJoin(sortParams, false);

            // 获取指定摘要算法的messageDigest对象
            MessageDigest messageDigest = null; // 此处的sha代表sha1
            try {
                messageDigest = MessageDigest.getInstance("SHA1");
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }

            // 调用digest方法，进行加密操作
            byte[] cipherBytes = messageDigest.digest(str.getBytes());

            String cipherStr = Hex.encodeHexString(cipherBytes);
            System.out.println(cipherStr);
            ret.put("appid", "wxf36d60fc160f5fdb");
            ret.put("timestamp", timestamp);
            ret.put("noncestr", noncestr);
            ret.put("signature", cipherStr);
            /*-----------------------*/
            System.out.println(timestamp);
            System.out.println(noncestr);
            System.out.println(cipherStr);
            return ret;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Map<String, String> makeWXAgentTicket(String url) {
        String jsApiTicket = null;
        try {
            String mAccess_token = WxAccessToken.getSavedAccessToken();
            jsApiTicket = WxAccessToken.getSavedAgentJsapiTicket(mAccess_token);

            Map<String, String> ret = new HashMap<String, String>();
            String timestamp = createTimestamp();
            String noncestr = getNonceStr();
            /*-----------------------*/
            Map<String, String> params = new HashMap<String, String>();
            params.put("jsapi_ticket", jsApiTicket);
            params.put("noncestr", noncestr);
            params.put("timestamp", timestamp);
            params.put("url", url);
            //1.1 对所有待签名参数按照字段名的ASCII 码从小到大排序（字典序）
            Map<String, String> sortParams = sortAsc(params);
            //1.2 使用URL键值对的格式拼接成字符串
            String str = mapJoin(sortParams, false);

            // 获取指定摘要算法的messageDigest对象
            MessageDigest messageDigest = null; // 此处的sha代表sha1
            try {
                messageDigest = MessageDigest.getInstance("SHA1");
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }

            // 调用digest方法，进行加密操作
            byte[] cipherBytes = messageDigest.digest(str.getBytes());

            String cipherStr = Hex.encodeHexString(cipherBytes);
            System.out.println(cipherStr);
            ret.put("appid", "wxf36d60fc160f5fdb");
            ret.put("timestamp", timestamp);
            ret.put("noncestr", noncestr);
            ret.put("signature", cipherStr);
            /*-----------------------*/
            System.out.println(timestamp);
            System.out.println(noncestr);
            System.out.println(cipherStr);
            return ret;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    private static String createTimestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }


    /**
     * 获取一定长度的随机字符串
     *
     * @param length 指定字符串长度
     * @return 一定长度的字符串
     */
    public static String getRandomStringByLength(int length) {
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

    public static String getNonceStr() {
        return getRandomStringByLength(16);
    }

    private static HashMap<String, String> sortAsc(Map<String, String> map) {
        HashMap<String, String> tempMap = new LinkedHashMap<String, String>();
        List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>(map.entrySet());
        //排序
        Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() {
            @Override
            public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
                return o1.getKey().compareTo(o2.getKey());
            }
        });

        for (int i = 0; i < infoIds.size(); i++) {
            Map.Entry<String, String> item = infoIds.get(i);
            tempMap.put(item.getKey(), item.getValue());
        }
        return tempMap;
    }


    public static String mapJoin(Map<String, String> map, boolean valueUrlEncode) {
        StringBuilder sb = new StringBuilder();
        for (String key : map.keySet()) {
            if (map.get(key) != null && !"".equals(map.get(key))) {
                try {
                    String temp = (key.endsWith("_") && key.length() > 1) ? key.substring(0, key.length() - 1) : key;
                    sb.append(temp);
                    sb.append("=");
                    //获取到map的值
                    String value = map.get(key);
                    //判断是否需要url编码
                    if (valueUrlEncode) {
                        value = URLEncoder.encode(map.get(key), "utf-8").replace("+", "%20");
                    }
                    sb.append(value);
                    sb.append("&");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
        }
        if (sb.length() > 0) {
            sb.deleteCharAt(sb.length() - 1);
        }
        return sb.toString();
    }
}
